package com.smart.community.region.controller;

import com.smart.community.region.entity.PropertyHouseType;
import com.smart.community.region.service.IPropertyHouseTypeService;
import com.smart.community.feign.region.dto.PropertyHouseTypeDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 物业公司户型配置Feign接口实现Controller
 * 
 * @author Wu.Liang
 * @version 2.0.0
 * @since 2025-01-30
 */
@Slf4j
@RestController
@RequestMapping("/feign/region/house-types")
@Tag(name = "户型配置Feign接口", description = "户型配置相关Feign接口")
public class PropertyHouseTypeFeignController {

    @Autowired
    private IPropertyHouseTypeService propertyHouseTypeService;

    /**
     * 根据ID获取户型配置详情
     * 
     * @param id 户型配置ID
     * @return 户型配置详情
     */
    @GetMapping("/{id}")
    @Operation(summary = "根据ID获取户型配置详情")
    public PropertyHouseTypeDTO getHouseTypeById(@Parameter(description = "户型配置ID") @PathVariable("id") Long id) {
        log.info("根据ID获取户型配置详情，户型ID：{}", id);
        try {
            PropertyHouseType houseType = propertyHouseTypeService.getHouseTypeById(id);
            PropertyHouseTypeDTO houseTypeDTO = convertToDTO(houseType);
            
            log.info("根据ID获取户型配置详情成功，户型ID：{}", id);
            return houseTypeDTO;
        } catch (Exception e) {
            log.error("根据ID获取户型配置详情失败，户型ID：{}", id, e);
            return new PropertyHouseTypeDTO();
        }
    }

    /**
     * 根据物业公司ID查询户型配置列表
     * 
     * @param propertyCompanyId 物业公司ID
     * @return 户型配置列表
     */
    @GetMapping("/property-company/{propertyCompanyId}")
    @Operation(summary = "根据物业公司ID查询户型配置列表")
    public List<PropertyHouseTypeDTO> getHouseTypesByPropertyCompanyId(@Parameter(description = "物业公司ID") @PathVariable("propertyCompanyId") Long propertyCompanyId) {
        log.info("根据物业公司ID查询户型配置列表，物业公司ID：{}", propertyCompanyId);
        try {
            List<PropertyHouseType> houseTypes = propertyHouseTypeService.getByPropertyCompanyId(propertyCompanyId);
            List<PropertyHouseTypeDTO> houseTypeDTOs = houseTypes.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            
            log.info("根据物业公司ID查询户型配置列表成功，物业公司ID：{}，数量：{}", propertyCompanyId, houseTypeDTOs.size());
            return houseTypeDTOs;
        } catch (Exception e) {
            log.error("根据物业公司ID查询户型配置列表失败，物业公司ID：{}", propertyCompanyId, e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据物业公司ID列表查询户型配置列表
     * 
     * @param propertyCompanyIds 物业公司ID列表
     * @return 户型配置列表
     */
    @PostMapping("/property-companies")
    @Operation(summary = "根据物业公司ID列表查询户型配置列表")
    public List<PropertyHouseTypeDTO> getHouseTypesByPropertyCompanyIds(@Parameter(description = "物业公司ID列表") @RequestBody List<Long> propertyCompanyIds) {
        log.info("根据物业公司ID列表查询户型配置列表，物业公司ID列表：{}", propertyCompanyIds);
        try {
            Map<Long, List<PropertyHouseType>> houseTypesMap = propertyHouseTypeService.getByPropertyCompanyIds(propertyCompanyIds);
            List<PropertyHouseType> allHouseTypes = new ArrayList<>();
            houseTypesMap.values().forEach(allHouseTypes::addAll);
            
            List<PropertyHouseTypeDTO> houseTypeDTOs = allHouseTypes.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            
            log.info("根据物业公司ID列表查询户型配置列表成功，物业公司数量：{}，户型数量：{}", propertyCompanyIds.size(), houseTypeDTOs.size());
            return houseTypeDTOs;
        } catch (Exception e) {
            log.error("根据物业公司ID列表查询户型配置列表失败，物业公司ID列表：{}", propertyCompanyIds, e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据物业公司ID列表获取户型列表（按物业公司分组）
     * 
     * @param propertyCompanyIds 物业公司ID列表
     * @return 按物业公司分组的户型列表
     */
    @PostMapping("/property-companies/grouped")
    @Operation(summary = "根据物业公司ID列表获取户型列表（按物业公司分组）")
    public Map<Long, List<PropertyHouseTypeDTO>> getHouseTypesByPropertyCompanyIdsGrouped(@Parameter(description = "物业公司ID列表") @RequestBody List<Long> propertyCompanyIds) {
        log.info("根据物业公司ID列表获取户型列表（按物业公司分组），物业公司ID列表：{}", propertyCompanyIds);
        try {
            Map<Long, List<PropertyHouseType>> houseTypes = propertyHouseTypeService.getByPropertyCompanyIds(propertyCompanyIds);
            Map<Long, List<PropertyHouseTypeDTO>> houseTypeDTOs = new HashMap<>();
            
            houseTypes.forEach((propertyCompanyId, houseTypeList) -> {
                List<PropertyHouseTypeDTO> dtoList = houseTypeList.stream()
                        .map(this::convertToDTO)
                        .collect(Collectors.toList());
                houseTypeDTOs.put(propertyCompanyId, dtoList);
            });
            
            log.info("根据物业公司ID列表获取户型列表（按物业公司分组）成功，物业公司数量：{}，总户型数量：{}", propertyCompanyIds.size(), 
                houseTypeDTOs.values().stream().mapToInt(List::size).sum());
            return houseTypeDTOs;
        } catch (Exception e) {
            log.error("根据物业公司ID列表获取户型列表（按物业公司分组）失败，物业公司ID列表：{}", propertyCompanyIds, e);
            return new HashMap<>();
        }
    }

    /**
     * 检查户型名称是否已存在
     * 
     * @param houseTypeName 户型名称
     * @param propertyCompanyId 物业公司ID
     * @param excludeId 排除的ID（用于更新时检查）
     * @return 是否已存在
     */
    @GetMapping("/check-name")
    @Operation(summary = "检查户型名称是否已存在")
    public Boolean isHouseTypeNameExists(
            @Parameter(description = "户型名称") @RequestParam("houseTypeName") String houseTypeName,
            @Parameter(description = "物业公司ID") @RequestParam("propertyCompanyId") Long propertyCompanyId,
            @Parameter(description = "排除的ID") @RequestParam(value = "excludeId", required = false) Long excludeId) {
        log.info("检查户型名称是否已存在，户型名称：{}，物业公司ID：{}，排除ID：{}", houseTypeName, propertyCompanyId, excludeId);
        try {
            Boolean exists = propertyHouseTypeService.checkHouseTypeNameExists(houseTypeName, propertyCompanyId, excludeId);
            log.info("检查户型名称是否已存在成功，户型名称：{}，物业公司ID：{}，结果：{}", houseTypeName, propertyCompanyId, exists);
            return exists;
        } catch (Exception e) {
            log.error("检查户型名称是否已存在失败，户型名称：{}，物业公司ID：{}", houseTypeName, propertyCompanyId, e);
            return false;
        }
    }

    /**
     * 批量获取户型配置详情
     * 
     * @param ids 户型配置ID列表
     * @return 户型配置详情列表
     */
    @PostMapping("/batch")
    @Operation(summary = "批量获取户型配置详情")
    public List<PropertyHouseTypeDTO> getHouseTypesByIds(@Parameter(description = "户型配置ID列表") @RequestBody List<Long> ids) {
        log.info("批量获取户型配置详情，户型ID列表：{}", ids);
        try {
            List<PropertyHouseType> houseTypes = propertyHouseTypeService.listByIds(ids);
            List<PropertyHouseTypeDTO> houseTypeDTOs = houseTypes.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            
            log.info("批量获取户型配置详情成功，户型ID数量：{}，返回数量：{}", ids.size(), houseTypeDTOs.size());
            return houseTypeDTOs;
        } catch (Exception e) {
            log.error("批量获取户型配置详情失败，户型ID列表：{}", ids, e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据户型名称模糊查询户型配置列表
     * 
     * @param houseTypeName 户型名称
     * @param propertyCompanyId 物业公司ID
     * @return 户型配置列表
     */
    @GetMapping("/search/name")
    @Operation(summary = "根据户型名称模糊查询户型配置列表")
    public List<PropertyHouseTypeDTO> searchHouseTypesByName(
            @Parameter(description = "户型名称") @RequestParam("houseTypeName") String houseTypeName,
            @Parameter(description = "物业公司ID") @RequestParam(value = "propertyCompanyId", required = false) Long propertyCompanyId) {
        log.info("根据户型名称模糊查询户型配置列表，户型名称：{}，物业公司ID：{}", houseTypeName, propertyCompanyId);
        try {
            // 使用MyBatis-Plus的lambdaQuery进行模糊查询
            List<PropertyHouseType> houseTypes = propertyHouseTypeService.lambdaQuery()
                    .like(PropertyHouseType::getHouseTypeName, houseTypeName)
                    .eq(propertyCompanyId != null, PropertyHouseType::getPropertyCompanyId, propertyCompanyId)
                    .list();
            
            List<PropertyHouseTypeDTO> houseTypeDTOs = houseTypes.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            
            log.info("根据户型名称模糊查询户型配置列表成功，户型名称：{}，物业公司ID：{}，数量：{}", houseTypeName, propertyCompanyId, houseTypeDTOs.size());
            return houseTypeDTOs;
        } catch (Exception e) {
            log.error("根据户型名称模糊查询户型配置列表失败，户型名称：{}，物业公司ID：{}", houseTypeName, propertyCompanyId, e);
            return new ArrayList<>();
        }
    }

    /**
     * 获取启用的户型配置列表
     * 
     * @param propertyCompanyId 物业公司ID
     * @return 启用的户型配置列表
     */
    @GetMapping("/enabled/{propertyCompanyId}")
    @Operation(summary = "获取启用的户型配置列表")
    public List<PropertyHouseTypeDTO> getEnabledHouseTypes(@Parameter(description = "物业公司ID") @PathVariable("propertyCompanyId") Long propertyCompanyId) {
        log.info("获取启用的户型配置列表，物业公司ID：{}", propertyCompanyId);
        try {
            // 使用MyBatis-Plus的lambdaQuery查询启用的户型
            List<PropertyHouseType> houseTypes = propertyHouseTypeService.lambdaQuery()
                    .eq(PropertyHouseType::getPropertyCompanyId, propertyCompanyId)
                    .eq(PropertyHouseType::getStatus, 1) // 假设1表示启用状态
                    .list();
            
            List<PropertyHouseTypeDTO> houseTypeDTOs = houseTypes.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            
            log.info("获取启用的户型配置列表成功，物业公司ID：{}，数量：{}", propertyCompanyId, houseTypeDTOs.size());
            return houseTypeDTOs;
        } catch (Exception e) {
            log.error("获取启用的户型配置列表失败，物业公司ID：{}", propertyCompanyId, e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据建筑面积范围查询户型配置
     * 
     * @param minArea 最小面积
     * @param maxArea 最大面积
     * @param propertyCompanyId 物业公司ID
     * @return 户型配置列表
     */
    @GetMapping("/search/area")
    @Operation(summary = "根据建筑面积范围查询户型配置")
    public List<PropertyHouseTypeDTO> searchHouseTypesByArea(
            @Parameter(description = "最小面积") @RequestParam("minArea") Double minArea,
            @Parameter(description = "最大面积") @RequestParam("maxArea") Double maxArea,
            @Parameter(description = "物业公司ID") @RequestParam(value = "propertyCompanyId", required = false) Long propertyCompanyId) {
        log.info("根据建筑面积范围查询户型配置，最小面积：{}，最大面积：{}，物业公司ID：{}", minArea, maxArea, propertyCompanyId);
        try {
            // 使用MyBatis-Plus的lambdaQuery进行范围查询
            List<PropertyHouseType> houseTypes = propertyHouseTypeService.lambdaQuery()
                    .ge(PropertyHouseType::getTotalArea, minArea)
                    .le(PropertyHouseType::getTotalArea, maxArea)
                    .eq(propertyCompanyId != null, PropertyHouseType::getPropertyCompanyId, propertyCompanyId)
                    .list();
            
            List<PropertyHouseTypeDTO> houseTypeDTOs = houseTypes.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            
            log.info("根据建筑面积范围查询户型配置成功，最小面积：{}，最大面积：{}，物业公司ID：{}，数量：{}", minArea, maxArea, propertyCompanyId, houseTypeDTOs.size());
            return houseTypeDTOs;
        } catch (Exception e) {
            log.error("根据建筑面积范围查询户型配置失败，最小面积：{}，最大面积：{}，物业公司ID：{}", minArea, maxArea, propertyCompanyId, e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据朝向查询户型配置
     * 
     * @param orientation 朝向
     * @param propertyCompanyId 物业公司ID
     * @return 户型配置列表
     */
    @GetMapping("/search/orientation")
    @Operation(summary = "根据朝向查询户型配置")
    public List<PropertyHouseTypeDTO> searchHouseTypesByOrientation(
            @Parameter(description = "朝向") @RequestParam("orientation") String orientation,
            @Parameter(description = "物业公司ID") @RequestParam(value = "propertyCompanyId", required = false) Long propertyCompanyId) {
        log.info("根据朝向查询户型配置，朝向：{}，物业公司ID：{}", orientation, propertyCompanyId);
        try {
            // 使用MyBatis-Plus的lambdaQuery进行查询
            List<PropertyHouseType> houseTypes = propertyHouseTypeService.lambdaQuery()
                    .eq(PropertyHouseType::getOrientation, orientation)
                    .eq(propertyCompanyId != null, PropertyHouseType::getPropertyCompanyId, propertyCompanyId)
                    .list();
            
            List<PropertyHouseTypeDTO> houseTypeDTOs = houseTypes.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            
            log.info("根据朝向查询户型配置成功，朝向：{}，物业公司ID：{}，数量：{}", orientation, propertyCompanyId, houseTypeDTOs.size());
            return houseTypeDTOs;
        } catch (Exception e) {
            log.error("根据朝向查询户型配置失败，朝向：{}，物业公司ID：{}", orientation, propertyCompanyId, e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据适用人群查询户型配置
     * 
     * @param suitableCrowd 适用人群
     * @param propertyCompanyId 物业公司ID
     * @return 户型配置列表
     */
    @GetMapping("/search/crowd")
    @Operation(summary = "根据适用人群查询户型配置")
    public List<PropertyHouseTypeDTO> searchHouseTypesByCrowd(
            @Parameter(description = "适用人群") @RequestParam("suitableCrowd") String suitableCrowd,
            @Parameter(description = "物业公司ID") @RequestParam(value = "propertyCompanyId", required = false) Long propertyCompanyId) {
        log.info("根据适用人群查询户型配置，适用人群：{}，物业公司ID：{}", suitableCrowd, propertyCompanyId);
        try {
            // 使用MyBatis-Plus的lambdaQuery进行查询
            List<PropertyHouseType> houseTypes = propertyHouseTypeService.lambdaQuery()
                    .eq(PropertyHouseType::getSuitableCrowd, suitableCrowd)
                    .eq(propertyCompanyId != null, PropertyHouseType::getPropertyCompanyId, propertyCompanyId)
                    .list();
            
            List<PropertyHouseTypeDTO> houseTypeDTOs = houseTypes.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            
            log.info("根据适用人群查询户型配置成功，适用人群：{}，物业公司ID：{}，数量：{}", suitableCrowd, propertyCompanyId, houseTypeDTOs.size());
            return houseTypeDTOs;
        } catch (Exception e) {
            log.error("根据适用人群查询户型配置失败，适用人群：{}，物业公司ID：{}", suitableCrowd, propertyCompanyId, e);
            return new ArrayList<>();
        }
    }

    /**
     * 获取户型配置统计信息
     * 
     * @param propertyCompanyId 物业公司ID
     * @return 统计信息
     */
    @GetMapping("/statistics/{propertyCompanyId}")
    @Operation(summary = "获取户型配置统计信息")
    public Object getHouseTypeStatistics(@Parameter(description = "物业公司ID") @PathVariable("propertyCompanyId") Long propertyCompanyId) {
        log.info("获取户型配置统计信息，物业公司ID：{}", propertyCompanyId);
        try {
            // 使用MyBatis-Plus的lambdaQuery进行统计
            long totalCount = propertyHouseTypeService.lambdaQuery()
                    .eq(PropertyHouseType::getPropertyCompanyId, propertyCompanyId)
                    .count();
            
            long enabledCount = propertyHouseTypeService.lambdaQuery()
                    .eq(PropertyHouseType::getPropertyCompanyId, propertyCompanyId)
                    .eq(PropertyHouseType::getStatus, 1) // 假设1表示启用状态
                    .count();
            
            Map<String, Object> statistics = new HashMap<>();
            statistics.put("totalCount", totalCount);
            statistics.put("enabledCount", enabledCount);
            statistics.put("disabledCount", totalCount - enabledCount);
            
            log.info("获取户型配置统计信息成功，物业公司ID：{}", propertyCompanyId);
            return statistics;
        } catch (Exception e) {
            log.error("获取户型配置统计信息失败，物业公司ID：{}", propertyCompanyId, e);
            return new HashMap<>();
        }
    }

    /**
     * 检查户型配置是否存在
     * 
     * @param id 户型配置ID
     * @return 是否存在
     */
    @GetMapping("/check/{id}")
    @Operation(summary = "检查户型配置是否存在")
    public Boolean checkHouseTypeExists(@Parameter(description = "户型配置ID") @PathVariable("id") Long id) {
        log.info("检查户型配置是否存在，户型ID：{}", id);
        try {
            Boolean exists = propertyHouseTypeService.getById(id) != null;
            log.info("检查户型配置是否存在成功，户型ID：{}，结果：{}", id, exists);
            return exists;
        } catch (Exception e) {
            log.error("检查户型配置是否存在失败，户型ID：{}", id, e);
            return false;
        }
    }
    
    /**
     * 将Entity转换为DTO
     * 
     * @param entity PropertyHouseType实体
     * @return PropertyHouseTypeDTO
     */
    private PropertyHouseTypeDTO convertToDTO(PropertyHouseType entity) {
        if (entity == null) {
            return new PropertyHouseTypeDTO();
        }
        
        PropertyHouseTypeDTO dto = new PropertyHouseTypeDTO();
        BeanUtils.copyProperties(entity, dto);
        return dto;
    }
}
